/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.ssau.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;
import java.util.List;
import ru.ssau.model.DataModel;
import ru.ssau.model.storing.DataAccessException;
import ru.ssau.presenter.ServerPresenter;

/**
 *
 * @author Дима
 */
public class Server {

    private ServerSocket serverSocket;
    private ServerPresenter presenter;
    private DataModel dataModel;

    //Сервер посылает какие-то сообщения ("server started" и т.п.)
    //В данном случае слушателем является интерфейс (cmd или GUI)
    private List<InfoMessageListener> listeners = new LinkedList<InfoMessageListener>();

    public Server(DataModel dataModel) {
        this.dataModel = dataModel;
    }

    public DataModel getDataModel() {
        return dataModel;
    }
    
    public void addInfoMessageListener(InfoMessageListener listener) {
        listeners.add(listener);
    }

    public void removeInfoMessageListener(InfoMessageListener listener) {
        listeners.remove(listener);
    }

    private void sendMessageToListeners(String message) {
        for(InfoMessageListener l: listeners) {
            l.receiveInfoMessage(message);
        }
    }

    public void startServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
        sendMessageToListeners("server started");
        while (true) {
            Socket s = serverSocket.accept();
            Thread t = new Thread(new ServerThreadHandler(s, dataModel));
            t.start();
        }
    }

    public void closeConnection() {
        try {
            if(serverSocket != null) {
                serverSocket.close();
                dataModel.closeStore();
            }
        } catch(IOException e) {
            //diong nothing
        } catch(DataAccessException e) {
            //Что будем делать, если закрыть подключение к базе не удалось?..
        }
    }

    private class ServerThreadHandler implements Runnable {

        Socket socket;
        DataModel dataModel;

        public ServerThreadHandler(Socket s, DataModel model) {
            socket = s;
            dataModel = model;
        }

        public void run() {
            try {
                sendMessageToListeners("another client connected");
                ServerPresenter presenter = new ServerPresenter(socket, dataModel);
                dataModel.addDataModelChangeListener(presenter);
                presenter.service();
            } catch(IOException e) {
                //e.printStackTrace();
                sendMessageToListeners("another client disconnected");
            } catch(ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
}
